# from fastapi.responses import HTMLResponse,JSONResponse
# from fastapi.templating import Jinja2Templates
# from fastapi.staticfiles import StaticFiles
from functools import lru_cache
from dataclasses import dataclass
from fastapi import (
    FastAPI,
    Cookie,
    Header,
    Path,
    Query,
    Form,
    Body,
    File,
    UploadFile,
    Depends,
    status,
    BackgroundTasks,
    HTTPException,
    Request,
    Security,
    WebSocket,
)
from fastapi.security import (
    OAuth2PasswordBearer,
    OAuth2PasswordRequestForm,
    OAuth2PasswordRequestFormStrict
)
from fastapi.responses import (
    ORJSONResponse,
    HTMLResponse,
    UJSONResponse,
    RedirectResponse,
    StreamingResponse,
    FileResponse,
    JSONResponse
)
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
# from unicorn import UnicornMiddleware
from typing_extensions import Annotated
from typing import Union #, List, Set, Any
from pydantic import BaseModel #, Field, EmailStr, HttpUrl
from datetime import datetime, timedelta, timezone
import uvicorn
from jose import JWTError, jwt
from passlib.context import CryptContext
import json

from routers import bilibili,sentinel
from dependencies import (
    get_current_active_user,
    Token,
    User,
    authenticate_user,
    get_current_user,
    create_access_token,
    get_current_username,
    security
)
from config import Settings


@lru_cache(maxsize=300)
def get_settings():return Settings()


settings = get_settings()


with open('app/user.json','r')as json_file:
    fake_users_db = json.load(json_file)

print(fake_users_db)
# pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

description = """
    FengYYApp API helps you do awesome stuff. 🚀

    You will be able to:
    1.下载哔哩哔哩视频、音频
    2.下载哥白尼哨兵数据
    3.上传视频，并分离音频与画面
    """


tags_metadata = [
    {
        "name": "bilibili",
        "description": "有关bilibili所有的数据操作。",
    },
    {
        "name": "sentinel",
        "description": "有关所有的哨兵2数据操作。",
        # "externalDocs": {
        #     "description": "Items external docs",
        #     "url": "https://fastapi.tiangolo.com/",
        # },
    },
]


app = FastAPI(
    title="FengYYApp",
    description=description,
    summary="Deadpool's favorite app. Nuff said.",
    version="0.0.1",
    terms_of_service="http://example.com/terms/",
    contact={
        "name": "Deadpoolio the Amazing",
        "url": "http://x-force.example.com/contact/",
        "email": "dp@x-force.example.com",
    },
    license_info={
        "name": "Apache 2.0",
        "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
    },
    dependencies=[
        # Depends(get_current_active_user),
    ],
    openapi_tags=tags_metadata,
    openapi_url="/openapi.json",
    docs_url="/doc", # None
    redoc_url="/redoc", # None
    )



app.add_middleware(GZipMiddleware, minimum_size=1000)
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["*"])
# app.add_middleware(HTTPSRedirectMiddleware)


@app.post("/token")
async def login_for_access_token(
    form_data: OAuth2PasswordRequestForm = Depends(),
) -> Token:
    user = authenticate_user(fake_users_db, form_data.username, form_data.password)
    if not user:
        raise HTTPException(status_code=400,detail="Incorrect username or password")
    access_token_expires = timedelta(
        minutes=settings.jwt_params.access_token_expire_minutes)
    access_token = create_access_token(
        data={"sub": user.username, "scopes": form_data.scopes},
        expires_delta=access_token_expires,
    )
    return Token(access_token=access_token, token_type="bearer")


# @app.get("/users/me/", response_model=User)
# async def read_users_me(current_user: User = Depends(get_current_active_user)):
#     return current_user

@app.get("/users/me")
def read_current_user(credentials: HTTPBasicCredentials = Depends(security)):
    return {"username": credentials.username, "password": credentials.password}


@app.get("/users/me/items/")
async def read_own_items(
    current_user: User = Security(get_current_active_user, scopes=["items"]),
):
    return [{"item_id": "Foo", "owner": current_user.username}]


@app.get("/status/")
async def read_system_status(current_user: User = Depends(get_current_user)):
    return {"status": "ok"}

app.mount(
    "/subapi", 
    # StaticFiles(directory="static"), 
    subapi,
    name="subapi",
)
app.include_router(bilibili.router)
app.include_router(sentinel.router)
# app.include_router(
#     admin.router,
#     prefix="/admin",
#     tags=["admin"],
#     dependencies=[Depends(get_token_header)],
#     responses={418: {"description": "I'm a teapot"}},
# )

# celery_app = Celery(
#     settings.redis_connection.name, 
#     broker=f'redis://:{settings.redis_connection.password}@{settings.redis_connection.host}:{settings.redis_connection.port}/{settings.redis_connection.brokerdb}', 
#     backend=f'redis://:{settings.redis_connection.password}@{settings.redis_connection.host}:{settings.redis_connection.port}/{settings.redis_connection.backenddb}'
#     )


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)